//
//  KCMessage.m
//  KConnect
//
//  Created on 18/03/09.
//  Copyright 2009 Xtreme Labs Inc. All rights reserved.
//


#define kUUIDLength 16
#define kUUIDShort  8
#define kUUIDBase   16

#import "KCMessage.h"


@interface KCMessage(Private)

-(void)verifyParameters;

@end

@implementation KCMessage

@synthesize parameters;

#pragma mark Public Methods

+ (NSString*)longUUID
{
  NSMutableString *longUUID = [NSMutableString string];
  
  for (int i = 0; i < kUUIDLength; i++) {
    [longUUID appendFormat:@"%0x", arc4random() % kUUIDBase ]; 
  }
  
  return [NSString stringWithString:longUUID];
}

+ (NSString*)shortUUID
{
  return [[KCMessage longUUID] substringToIndex:kUUIDShort];
}


- (id)initWithParameters:(NSDictionary *)someParameters
{
	if (self = [super init])
	{
    self.parameters = [NSMutableDictionary dictionaryWithDictionary:someParameters];
		[self verifyParameters];
	}
	
	return self;
}

- (NSString*)URL
{
  NSMutableString * url = [NSMutableString string];
  [url appendFormat:@"%@/?", [self messageType]];
  
  NSEnumerator *enumerator = [parameters keyEnumerator];
  id key;
  BOOL first = YES;
  
  while (key = [enumerator nextObject]) {
    
    if (!first) 
      [url appendFormat:@"&"];  
    else
      first = NO;
      
    [url appendFormat:@"%@=%@", key, [parameters objectForKey:key]];
  }
  
  return url;
}

- (NSString*)buildCommaString:(NSArray*)strings
{
  //Build recipients string
  NSMutableString *rec = [NSMutableString string];
  
  for (NSString * string in strings)
  { 
    if (![rec isEqualToString:@""]) 
    {
      [rec appendString:@","];
    }
    
    [rec appendString:string];
  }
  
  return rec;
}

- (NSString*)messageType
{
	return [NSString string];
}

- (NSArray*)requiredParameters
{
	return [NSArray array];
}

- (NSArray*)optionalParameters
{
	return [NSArray array];
}

- (void)addOptionalParameter:(NSString*)key value:(NSString*)value
{
  [self addOptionalParameter:key value:value verify:YES];
}

- (void)addOptionalParameter:(NSString*)key value:(NSString*)value verify:(BOOL)verify
{
  [self.parameters setObject:value forKey:key];
  if (verify)
    [self verifyParameters]; 
}

#pragma mark Private Methods

-(void)verifyParameters
{
  NSArray * required = [self requiredParameters];
	NSArray * optional = [self optionalParameters];
	
  
  //Ensure required parameters are present
	for (NSString * key in required)
	{
		if ([self.parameters objectForKey:key] == nil)
		{
			NSString *reason = [NSString stringWithFormat:@"Parameter '%@' is missing", key];

			NSException *exception = [NSException exceptionWithName:@"MissingParameterException" 
                                                       reason:reason 
                                                     userInfo:nil];
      
      @throw exception;
		}
	}
  
  
  //Ensure no unexpected parameters are present
  for (NSString * key in self.parameters)
  {
    if (![optional containsObject:key] && ![required containsObject:key])
    {
      NSString *reason = [NSString stringWithFormat:@"Parameter '%@' is unexpected", key];
      
			NSException *exception = [NSException exceptionWithName:@"UnexpectedParameterException" 
                                                       reason:reason
                                                     userInfo:nil];
      @throw exception;      
    }
  }
}

@end
